<script setup lang='ts'>
import { nextTick, onMounted, reactive, ref, watch } from 'vue';
const props = withDefaults(defineProps<{
    show?: boolean,
    title?: string,
    width?: number,
    height?: number | string,
    left?: number,
    top?: number,
    isDblclick?: boolean
}>(), {
    show: true,
    title: '设置',
    width: 700,
    height: 400,
    isDblclick: false,
    top: 0,
    left: 0
});
import { ElMessage } from "element-plus";


const emits = defineEmits(['close']);

const containerStyle = reactive<any>({ width: 700, height: 400, top: 0, left: 0 })
const container = ref<HTMLDivElement>()
const isdragEagle = ref(false)
// const domStyle = ref({ width: '700px', height: '400px', top: 'calc(50% - 200px)', left: 'calc(50% - 350px)' })
const domStyle = ref<any>({})

const defaultStyle = async () => {
    containerStyle.width = props.width;
    // @ts-ignore
    containerStyle.height = props.height;
    if (props.left && props.top) {
        containerStyle.left = props.left;
        containerStyle.top = props.top;
    } else {
        const body = document.body;
        const uiWidth = body.clientWidth;
        const uiHeight = body.clientHeight;
        // @ts-ignore
        containerStyle.top = uiHeight / 2 - props.height / 2;
        containerStyle.left = uiWidth / 2 - props.width / 2;
    }
}

const initStyle = async () => {
    await nextTick();
    if (!container.value) return;
    defaultStyle();
    updateStyle();
}

const updateStyle = () => {
    if (!container.value) return;
    const { width, height, top, left } = containerStyle;
    domStyle.value.width = width + 'px';
    domStyle.value.height = height != "auto" ? height + 'px' : height;
    domStyle.value.top = top + 'px';
    domStyle.value.left = left + 'px';
}

watch(() => props.show, (val) => { val && initStyle() }, { immediate: true });

const dragEagle = (e1: MouseEvent) => {
    moveUp();
    if (!container.value) return;
    isdragEagle.value = true;

    // 修复1：改用client坐标（包含缩放因素）
    const startX = e1.clientX;
    const startY = e1.clientY;

    // 修复2：实时获取初始位置（兼容缩放后状态）
    const initialLeft = container.value.offsetLeft;
    const initialTop = container.value.offsetTop;

    const onMouseMove = (e: MouseEvent) => {
        if (!container.value) return;
        e.stopPropagation();

        // 修复3：动态计算最大边界
        const currentMaxWidth = document.documentElement.clientWidth;
        const currentMaxHeight = document.documentElement.clientHeight;

        // 修复4：基于初始位置的增量计算
        let left = initialLeft + (e.clientX - startX);
        let top = initialTop + (e.clientY - startY);

        // 修复5：简化边界约束逻辑
        left = Math.max(0, Math.min(left, currentMaxWidth - containerStyle.width));
        top = Math.max(0, Math.min(top, currentMaxHeight - container.value.offsetHeight));

        // 修复6：使用RAF批量更新
        requestAnimationFrame(() => {
            containerStyle.left = left;
            containerStyle.top = top;
            updateStyle();
        });
    };

    const onMouseUp = () => {
        isdragEagle.value = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
    };

    // 修复7：正确的事件监听方式
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
};


const moveUp = () => {
    if (!container.value) return;
    const dialogs = document.querySelectorAll('.modal-container') as NodeListOf<HTMLDivElement>;
    dialogs.forEach((dialog) => { dialog.style.zIndex = '99'; });
    container.value.style.zIndex = '100';
}

// 修正版节流函数（保留this）
function throttle(fn: any, delay: any) {
    let lastCall = 0;
    let savedThis, savedArgs;

    return function (...args: any) { // 改用传统函数
        const now = Date.now();
        // @ts-ignore
        savedThis = this; // 捕获当前this
        savedArgs = args;

        if (now - lastCall >= delay) {
            fn.apply(savedThis, savedArgs);
            lastCall = now;
        }
    }
}

const handleResize = () => {
    if (!container.value) return;
    const rect = container.value.getBoundingClientRect();

    // 自适应重定位（保证窗口可见）
    const maxX = window.innerWidth - rect.width - 10;
    const maxY = window.innerHeight - rect.height - 10;

    // @ts-ignore
    container.value.style.left = `${Math.min(parseInt(rect.left), maxX)}px`;
    // @ts-ignore
    container.value.style.top = `${Math.min(parseInt(rect.top), maxY)}px`;
}

onMounted(async () => {
    await nextTick(moveUp);
    // 窗口缩放监听（带节流）
    window.addEventListener('resize', throttle(() => handleResize(), 100));
});

// 双击复制名称
const dblclick = () => {
    if (!props.isDblclick) return;
    const input = document.createElement('input');
    input.value = props.title;
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
    ElMessage.success('复制成功');
}


const setSize = async () => {
    await nextTick()
    if (!container.value) return;
    const { width, height } = containerStyle;
    domStyle.value.width = width + 'px'
    domStyle.value.height = height + 'px'
}

const resize = (e: MouseEvent) => {
    if (!container.value) return
    isdragEagle.value = true
    const dom = document.body
    const maxWidth = dom.clientWidth - containerStyle.left;
    const maxHeight = dom.clientHeight - containerStyle.top;

    document.onmousemove = function (e: MouseEvent) {
        e.stopPropagation();
        //计算当前鼠标位置和全局点击位置的偏插值，尝试修改宽度和高度
        const w = e.movementX + containerStyle.width;
        // @ts-ignore

        const h = e.movementY + container.value.offsetHeight;

        if (w >= 300 && w <= maxWidth) {
            containerStyle.width = w;
        }
        if (h >= 200 && h <= maxHeight) {
            // @ts-ignore
            // container.value.offsetHeight = h;
            containerStyle.height = h;

        }
        setSize();
    }

    document.onmouseup = function () {
        isdragEagle.value = false
        document.onmousemove = null
        document.onmouseup = null
    }
}

</script>

<template>
    <div class="modal-container" @click.stop="moveUp" v-if="show" ref="container" :style="domStyle"
        :class="{ 'modal-box': isdragEagle }">
        <div class="modal-header" @mousedown.stop="dragEagle" @dblclick="dblclick">
            <div class="modal-title"> {{ title }}</div>
            <div class="modal-close" @click.stop="$emit('close')">✕</div>
        </div>
        <div class="modal-body">
            <slot></slot>
        </div>
        <i @mousedown.stop="resize" class="bar"></i>
    </div>
</template>

<style scoped>
.modal-container {
    position: fixed;
    color: black;
    z-index: 99;
    overflow: hidden;
    pointer-events: all;
    min-width: 300px;
    min-height: 70px;
    background: #fff;
    box-sizing: border-box;
    /* border: 1px solid #0000007e; */
    border-radius: 5px;
    box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5)
}

.modal-box {
    transition: none !important;
}

.modal-header {
    width: 100%;
    height: 36px;
    line-height: 36px;
    /* background-color: #0000007e; */
    display: flex;
    justify-content: space-between;
    align-items: center;
    user-select: none;
}

.modal-title {
    width: calc(100% - 36px);
    height: 36px;
    line-height: 36px;
    text-align: center;
    font-weight: 700;
    cursor: grab;
    font-size: 16px;
    overflow: hidden;

}

.modal-close {
    width: 36px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    font-size: 20px;
    cursor: pointer;
}

.modal-close:hover {
    font-weight: 700;
}

.modal-body {
    width: 100%;
    height: calc(100% - 36px);
    overflow: auto;
}

.bar {
    position: absolute;
    height: 10px;
    width: 10px;
    bottom: 0px;
    right: 0px;
    cursor: nw-resize;
    background: linear-gradient(135deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0) 50%, #373737 50%, #a5a5a5 100%);
}
</style>
